<?php

namespace App\Services;

use App\Models\Payment;
use EasyWeChat\Factory;
use Illuminate\Support\Facades\DB;

class CzOrderService
{
    protected $payApp;
    public function __construct()
    {
        $appid = env('appid');
        $mch_id = env('mch_id');
        $key = env('key');
        $notify_url = env('notify_url');
        $config = [
            'app_id' => $appid,
            'mch_id' => $mch_id,
            'key' => $key,
            'cert_path' => base_path('payFile/apiclient_cert.pem'),
            'key_path' =>  base_path('payFile/apiclient_key.pem'),
            'notify_url' => $notify_url
        ];
        $this->payApp = Factory::payment($config);
    }
    // public function refundNew($orderInfo, $msg)
    // {
    //     if ($orderInfo->order_status != 4) {
    //         return ['result' => false, 'msg' => "非失败订单不退款"];
    //     }

    //     $is_refund_order = DB::table('order_refund')->where('order_id', $orderInfo->id)->first();
    //     if ($is_refund_order) {
    //         // return error('订单已退过款');
    //         return ['result' => false, 'msg' => "订单已退过款"];
    //     }

    //     $price = floatval($orderInfo->price);
    //     // 1todo退款金额
    //     $price = number_format($price, 2, '.', '');
    //     $price = intval(strval($price * 10000 / 100));

    //     // 退款
    //     $pay_type = $orderInfo->pay_type;
    //     $order_sn = $orderInfo->order_sn;
    //     if (!$pay_type || $pay_type == "wx") {
    //         $result = $this->payApp->refund->byOutTradeNumber($orderInfo->order_sn, $orderInfo->order_sn, $price, $price, [
    //             // 可在此处传入其他参数，详细参数见微信支付文档
    //             // 'refund_desc' => mb_substr($msg, 0, 80),
    //             'refund_desc' => $orderInfo->mobile . "充值失败退款",
    //         ]);
    //         if ($result['return_code'] == 'SUCCESS') {
    //             if ($result['result_code'] == 'SUCCESS') {

    //                 // 直接修改为退款成功
    //                 DB::table('cz_order')->where('id', $orderInfo->id)->update([
    //                     'msg' => '微信退款成功',
    //                     'refund_status' => 1,
    //                     "updated_at" => time()
    //                 ]);
    //                 return ['result' => true, 'msg' => '微信退款成功'];
    //             } else if ($result['err_code_des']) {
    //                 DB::table('cz_order')->where('id', $orderInfo->id)->update([
    //                     'msg' => '申请退款失败原因:' . $result['err_code_des'],
    //                     'refund_status' => 2,
    //                     // "updated_at" => time()
    //                 ]);
    //                 return ['result' => false, 'msg' => $result['err_code_des']];
    //             }
    //         } else {
    //             if ($result['return_msg']) {
    //                 $reson = $result['return_msg'];
    //             } else {
    //                 $reson = '未知错误';
    //             }
    //             DB::table('cz_order')->where('id', $orderInfo->id)->update([
    //                 'msg' => '申请退款失败原因:' . $reson,
    //                 'refund_status' => 2,
    //             ]);
    //             return ['result' => false, 'msg' => $reson];
    //         }
    //     } else {
    //         // 第三方退款
    //         // $payObj = PaymentService::getPayChannelById($payment_id);
    //         $payObj = $this->getPayChannelById($pay_type);
    //         $refund_order_sn = $order_sn . 'r' . rand(1000, 9999);
    //         $pay_order_sn = $orderInfo->pay_order_sn;
    //         logger('order_sn' . $order_sn . "pay_order_sn" . $pay_order_sn);
    //         // $refund_res = $payObj->refund($order_sn, $refund_order_sn, $price, substr($msg, 0, 80), $pay_order_sn);
    //         $refund_res = $payObj->refund($order_sn, $refund_order_sn, $price, $orderInfo->mobile . "充值失败退款", $pay_order_sn, json_decode(json_encode($orderInfo), true));

    //         logger("第三方退款返回参数" . json_encode($refund_res));
    //         if ($refund_res['code'] == 200) {
    //             // 直接修改为退款成功，真实情况是查询退款状态在同步
    //             DB::transaction(function () use ($orderInfo, $refund_order_sn) {
    //                 DB::table('cz_order')->where('id', $orderInfo->id)->update([
    //                     'msg' => '第三方退款成功',
    //                     'refund_status' => 1,
    //                     "updated_at" => time()
    //                 ]);
    //                 DB::table('order_refund')->insert([
    //                     "order_id" => $orderInfo->id,
    //                     "created_at" => time(),
    //                     "updated_at" => time(),
    //                     "create_by" => $orderInfo->create_by,
    //                     "update_by" => $orderInfo->update_by,
    //                     "refund_order_sn" => $refund_order_sn,
    //                     "remark" => $refund_res['msg'] ?? ''
    //                 ]);
    //             });
    //             return ['result' => true, 'msg' => '第三方退款成功'];
    //         } else {
    //             DB::table('cz_order')->where('id', $orderInfo->id)->update([
    //                 'msg' => '申请退款失败原因:' . $refund_res['msg'],
    //                 'refund_status' => 2,
    //                 // "updated_at" => time()
    //             ]);
    //             return ['result' => true, '申请退款失败原因:' . $refund_res['msg']];
    //         }
    //     }
    // }
    public function refund($orderInfo, $msg)
    {
        if ($orderInfo->order_status != 4) {
            return ['result' => false, 'msg' => "非失败订单不退款"];
        }

        $is_refund_order = DB::table('order_refund')->where('order_id', $orderInfo->id)->first();
        if ($is_refund_order) {
            // return error('订单已退过款');
            return ['result' => false, 'msg' => "订单已退过款"];
        }

        $price = floatval($orderInfo->price);
        // 1todo退款金额
        $price = number_format($price, 2, '.', '');
        $price = intval(strval($price * 10000 / 100));

        // 退款
        $pay_type = $orderInfo->pay_type;
        $order_sn = $orderInfo->order_sn;
        if (!$pay_type || $pay_type == "wx") {
            $result = $this->payApp->refund->byOutTradeNumber($orderInfo->order_sn, $orderInfo->order_sn, $price, $price, [
                // 可在此处传入其他参数，详细参数见微信支付文档
                // 'refund_desc' => mb_substr($msg, 0, 80),
                'refund_desc' => $orderInfo->mobile . "充值失败退款",
            ]);
            if ($result['return_code'] == 'SUCCESS') {
                if ($result['result_code'] == 'SUCCESS') {

                    // 直接修改为退款成功
                    DB::table('cz_order')->where('id', $orderInfo->id)->update([
                        'msg' => '微信退款成功',
                        'refund_status' => 1,
                        "updated_at" => time()
                    ]);
                    return ['result' => true, 'msg' => '微信退款成功'];
                } else if ($result['err_code_des']) {
                    DB::table('cz_order')->where('id', $orderInfo->id)->update([
                        'msg' => '申请退款失败原因:' . $result['err_code_des'],
                        'refund_status' => 2,
                        // "updated_at" => time()
                    ]);
                    return ['result' => false, 'msg' => $result['err_code_des']];
                }
            } else {
                if ($result['return_msg']) {
                    $reson = $result['return_msg'];
                } else {
                    $reson = '未知错误';
                }
                DB::table('cz_order')->where('id', $orderInfo->id)->update([
                    'msg' => '申请退款失败原因:' . $reson,
                    'refund_status' => 2,
                ]);
                return ['result' => false, 'msg' => $reson];
            }
        } else {
            // 第三方退款
            // $payObj = PaymentService::getPayChannelById($payment_id);
            if ($orderInfo->pay_id) {
                $payObj = $this->getPayChannelByIdV2($pay_type);
            } else {
                $payObj = $this->getPayChannelById($pay_type);
            }

            $refund_order_sn = $order_sn . 'r' . rand(1000, 9999);
            $pay_order_sn = $orderInfo->pay_order_sn;
            logger('order_sn' . $order_sn . "pay_order_sn" . $pay_order_sn);
            // $refund_res = $payObj->refund($order_sn, $refund_order_sn, $price, substr($msg, 0, 80), $pay_order_sn);
            $refund_res = $payObj->refund($order_sn, $refund_order_sn, $price, $orderInfo->mobile . "充值失败退款", $pay_order_sn, json_decode(json_encode($orderInfo), true));

            logger("第三方退款返回参数" . json_encode($refund_res));
            if ($refund_res['code'] == 200) {
                // 直接修改为退款成功，真实情况是查询退款状态在同步
                DB::transaction(function () use ($orderInfo, $refund_order_sn) {
                    DB::table('cz_order')->where('id', $orderInfo->id)->update([
                        'msg' => '第三方退款成功',
                        'refund_status' => 1,
                        "updated_at" => time()
                    ]);
                    DB::table('order_refund')->insert([
                        "order_id" => $orderInfo->id,
                        "created_at" => time(),
                        "updated_at" => time(),
                        "create_by" => $orderInfo->create_by,
                        "update_by" => $orderInfo->update_by,
                        "refund_order_sn" => $refund_order_sn,
                        "remark" => $refund_res['msg'] ?? ''
                    ]);
                });
                return ['result' => true, 'msg' => '第三方退款成功'];
            } else {
                DB::table('cz_order')->where('id', $orderInfo->id)->update([
                    'msg' => '申请退款失败原因:' . $refund_res['msg'],
                    'refund_status' => 2,
                    // "updated_at" => time()
                ]);
                return ['result' => true, '申请退款失败原因:' . $refund_res['msg']];
            }
        }
    }
    protected function getPayChannelByIdV2($pay_channel_id, $type = "cz")
    {
        $channel_info = Payment::find($pay_channel_id);
        $setting_arr = $channel_info->setting;
        $setting = [];
        foreach ($setting_arr as $v) {
            $setting[$v['name']] = $v['val'];
        }
        $setting['channel_code'] = $channel_info->payment_code;
        $setting['channel_id'] = $pay_channel_id;
        $setting['callback_url'] = $channel_info->callback_url;
        $temp_file = $channel_info->file_path ?? $channel_info->channel_code;
        $channel_file = base_path("payChannel/" . $temp_file . ".php");
        include_once $channel_file;
        // dd($setting);
        $obj = new $channel_info['payment_code']($setting);
        return $obj;
    }
    protected function getPayChannelById($id)
    {
        // if ($id == "jinfu" || $id == "jinfu2") {

        if ($id == "jinfu") {
            $channel_file = base_path("payChannel/jinfu/" . "jinfu.php");
            include_once $channel_file;
            $callback_url = env("third_notify_url") . "/jinfu";
            $setting = [
                "account" => env('third_account'),
                "key" => env('third_key'),
                "callback_url" => $callback_url,
            ];
            $payClassName = "jinfu";
            $obj = new $payClassName($setting);
            return $obj;
        }
        if ($id == "jinfu2") {
            $channel_file = base_path("payChannel/jinfu/" . "jinfu.php");
            include_once $channel_file;
            $callback_url = env("third_notify_url") . "/jinfu2";
            $setting = [
                "account" => env('third_account2'),
                "key" =>  env('third_key2'),
                "callback_url" => $callback_url,
            ];
            $payClassName = "jinfu";
            $obj = new $payClassName($setting);
            return $obj;
        }
        if ($id == "tlhsb") {
            $channel_file = base_path("payChannel/tlhsb/" . "tlhsb.php");
            include_once $channel_file;
            $callback_url = env("third_notify_url") . "/tlhsb";
            $setting = config('pay')['tlhsb'];
            $setting['callback_url'] = $callback_url;
            $payClassName = "tlhsb";
            $obj = new $payClassName($setting);
            return $obj;
        }
        if ($id == "tlhsb_yc_1YJT") {
            $channel_file = base_path("payChannel/tlhsb/" . "tlhsb.php");
            include_once $channel_file;
            $callback_url = env("third_notify_url") . "/tlhsb_yc_1YJT";
            $setting = config('pay')['tlhsb_yc_1YJT'];
            $setting['callback_url'] = $callback_url;
            $payClassName = "tlhsb";
            $obj = new $payClassName($setting);
            return $obj;
        }
        if ($id == "tlhsb_yc") {
            $channel_file = base_path("payChannel/tlhsb/" . "tlhsb.php");
            include_once $channel_file;
            $callback_url = env("third_notify_url") . "/tlhsb_yc";
            $setting = config('pay')['tlhsb_yc'];
            $setting['callback_url'] = $callback_url;
            $payClassName = "tlhsb";
            $obj = new $payClassName($setting);
            return $obj;
        }
        if ($id == "huilian") {
            $channel_file = base_path("payChannel/huilian/" . "huilian.php");
            include_once $channel_file;
            $callback_url = env("third_notify_url") . "/huilian";
            $setting = config('pay')['huilian'];
            $setting['callback_url'] = $callback_url;
            $payClassName = "huilian";
            $obj = new $payClassName($setting);
            return $obj;
        }
        // 严选无忧
        if ($id == "huifu_yxwy") {
            $channel_file = base_path("payChannel/huilian/" . "huilian.php");
            include_once $channel_file;
            $callback_url = env("third_notify_url") . "/huifu_yxwy";
            $setting = config('pay')['huifu_yxwy'];
            $setting['callback_url'] = $callback_url;
            $payClassName = "huilian";
            $obj = new $payClassName($setting);
            return $obj;
        }
        if ($id == "huilian_022") {
            $channel_file = base_path("payChannel/huilian/" . "huilian.php");
            include_once $channel_file;
            $callback_url = env("third_notify_url") . "/huilian_022";
            $setting = config('pay')['huilian_022'];
            $setting['callback_url'] = $callback_url;
            $payClassName = "huilian";
            $obj = new $payClassName($setting);
            return $obj;
        }
        if ($id == "huilian_022_si") {
            $channel_file = base_path("payChannel/huilian/" . "huilian.php");
            include_once $channel_file;
            $callback_url = env("third_notify_url") . "/huilian_022_si";
            $setting = config('pay')['huilian_022_si'];
            $setting['callback_url'] = $callback_url;
            $payClassName = "huilian";
            $obj = new $payClassName($setting);
            return $obj;
        }
        if ($id == "huilian2") {
            $channel_file = base_path("payChannel/huilian2/" . "huilian2.php");
            include_once $channel_file;
            $callback_url = env("third_notify_url") . "/huilian2";
            $setting = config('pay')['huilian2'];
            $setting['callback_url'] = $callback_url;
            $payClassName = "huilian2";
            $obj = new $payClassName($setting);
            return $obj;
        }
        if ($id == "huifuYxkx") {
            $channel_file = base_path("payChannel/huilian/" . "huilian.php");
            include_once $channel_file;
            $callback_url = env("third_notify_url") . "/huifuYxkx";
            $setting = config('pay')['huifuYxkx'];
            $setting['callback_url'] = $callback_url;
            $payClassName = "huilian";
            $obj = new $payClassName($setting);
            return $obj;
        }
        if ($id == "hstyYXkx") {
            $channel_file = base_path("payChannel/hsty/" . "hsty.php");
            include_once $channel_file;
            $callback_url = env("third_notify_url") . "/hstyYXkx";
            $setting = config('pay')['hstyYXkx'];
            $setting['callback_url'] = $callback_url;
            $payClassName = "hsty";
            $obj = new $payClassName($setting);
            return $obj;
        }
    }
    // }
}
